The approaches described in this section could be pursued, but are not necessarily approaches that have been previously conceived or pursued. Therefore, unless otherwise indicated herein, the approaches described in this section are not prior art to the claims in this application and are not admitted to be prior art by inclusion in this section.
In database applications, client-based applications typically interact with a database system to access and manipulate objects inside of one or more databases. Client-based applications may include application server-based code, such as code that runs within machines that process requests sent from web browsers and other “thin” client applications, as well as standalone code on machines running “thick” client applications, including code running on the same machine as the database system. Collectively, client-based applications may be referred to as “clients.”
Databases within a database system store a variety of objects. A database may define an object through metadata in a database. A database may store an object's actual contents (e.g. data, compiled code, and so on) as a representation residing in-memory, on a storage device, or in any other database-accessible location.
Particularly common in a database are data objects, which define, store, and reference the data in the database. Among the many types of data objects are tables, views, synonyms, and materialized views. A table, for example, may store data values in rows and columns. Database systems use another type of object, called a view, to provide “virtual” tables. In addition to data, objects may also comprise units of code, such as stored procedure code or program units, that run within the database system.
Instead of containing data values, a view may define rows and columns that are mapped to rows and columns of one or more “base tables” in a database, thereby offering applications an alternative or filtered “view” of the data in the database. Views may be referenced in database languages statements that conform to database language (e.g. SQL), and be treated by a database system as references to tables. Typically, a view is defined by a data definition language statement issued to the database system that specifies a query to define the view.
Both objects and data may be accessed, manipulated, and utilized either directly or indirectly in operations performed by the database system. A client may request that the database system perform an operation through a query. A query may, for example, be represented in a database language, including SQL (both ANSI and proprietary standards) or PL/SQL, a procedural database language promulgated by Oracle Corporation. Database operations may also be performed in response to a variety of other events, such as maintenance operations, internally issued queries, and internally executed stored procedure code.
Database applications often require upgrades to expand functionality, fix bugs, or increase security. An upgrade may be performed by software following steps coded by an application upgrade provider. Various upgrade steps may also be performed by other pieces of software or by a system administrator. Steps performed during an upgrade by the above-mentioned entities or units may, for brevity, be said to be performed by an “upgrade” or “upgrade process.”
Upgrades typically require changes to objects and data within the databases of a database system. An upgrade to a database application may change, for example, metadata about available database tables, such as which columns exist, what type of data each column contains, what constraints are enforced, and so on. Additionally, the actual contents of the existing data in the tables may need to be “transformed” to correct errors in the data or change the data to a different format or type. For instance, an upgrade may transform the data type of a column from string to date or from integer to decimal. As another example, an upgrade may need to transform values in one column from degrees Fahrenheit to degrees Celsius. As another example, an upgrade could transform a “full name” column into two columns: one for a first name and one for a last name.
Upgrades may also require changes to other database objects, such as stored procedure code, as well as to clients. Data changes may necessitate changes to both stored procedure code and the code behind client-based applications. Code must be updated or recompiled to accommodate changes in nomenclature, data types, or storage schemes for the data and objects that the code references. For instance, stored procedure code that has been compiled under the assumption that a certain table has two columns may have to be recompiled if that table now has three columns. An upgrade may also change both client-based and stored procedure code to fix bugs or provide new functionality.
The changes made to the various components of a database application during the upgrade process are dependent upon each other for proper behavior of the database application. The application will not run with correct results if a component interacts with components whose versions of code and data are incompatible with the component. For example, if a database has been upgraded so that a column is now named C1, but a client has not been updated and thinks the column is named C0, the client will not be able to access the data from that column.
To avoid the undesirable side effects of application components interacting with incompatible components, application upgrades may require turning off real-world use of the application while upgrading all of the components of that application. The resulting application “downtime” (i.e. the period of time during which the application cannot be used) often lasts multiple days. Downtime for any noticeable period is very undesirable, especially as users increasingly expect access to database applications twenty-four hours a day, seven days a week. Consequently, system administrators are often hesitant to upgrade applications, even when an upgrade provides better security or highly desirable features.
To avoid downtime, many application vendors limit themselves as much as possible to upgrades in which data values do not need to be modified or rearranged in a manner that is incompatible with the data expected by the pre-upgrade application. To the extent it is possible to avoid incompatibilities between upgraded and non-upgraded components, this strategy allows continued use of the pre-upgrade version of the application as use of the post-upgrade application is “phased-in.” Unfortunately, there are many bug fixes and feature additions that cannot be implemented without breaking compatibility with the pre-upgrade version of the application. Furthermore, it is often more costly and time-consuming to develop upgrades that maintain compatibility with prior application versions.
Another approach to reducing downtime for application upgrades is to combine database replication technology with software that captures data changes by pre-upgrade components of an application and replays them into a database copy used exclusively by the post-upgrade version of the application. In such an approach, a system administrator will create a new copy of a database, with which an upgraded client can interact. Specially designed synchronization software captures data changes made by pre-upgrade application components and reformats or modifies the changed data to be appropriate for the post-upgrade application. The changes are then copied to the new database.
Database replication approaches suffer from several problems. First, the clients must be reconfigured to use the new database, even though many clients might not otherwise require changes during the upgrade. Second, this approach requires the duplication of many resources, such as objects and data that do not actually change during the upgrade. For example, an upgrade may only affect a table T0 in a database, but nonetheless require duplication of all objects in the database. This approach may thus consume more memory resources than desirable. Finally, in cases where both versions of the application are allowed to run simultaneously in order to provide continuous service, such an approach suffers from merge and ordering difficulties. In other words, the same data being processed by one version of the application may have already been processed and changed within the database used by the other version of the application. For example, the same widget may have been allocated from a warehouse to satisfy a different purchase order from a different customer using a different version of the application. This behavior results because the separate copies of data used by the two versions of the application are not kept tightly enough synchronized for the two versions of the application to see each other's changes in a sufficiently timely manner.
One variation of this approach is to duplicate a schema instead of an entire database. This variation is useful when the data used by a database application resides solely within one schema. While replication of the schema avoids the memory costs associated with replication of the entire database, many resources that do not need to be replicated are nonetheless replicated. Furthermore coding the upgraded clients to work with a new schema often involves tedious reconstruction of account permissions, as well as reconfiguration of clients to work with the new schema. Finally, schema replication does nothing to solve merge and ordering problems.
A less wasteful variation of this approach in terms of memory costs is to replicate only those tables affected by the upgrade. However, this approach requires renaming the upgraded tables, since the upgraded tables could not share the same name as the pre-upgraded tables. Renaming tables, in turn, requires extensive updating of code. It may again require reconstruction of user permissions. Finally, renaming tables does not solve merge and ordering problems.
Other variations of the database replication approach have been made based on capturing application transactions at a higher level of abstraction, rather than on capturing changes to individual data items, and replaying the transactions in the post-upgrade version of the application. This can sometimes avoid the need for special software to reformat and modify the individual data items to make them appropriate for the post-upgrade application, but often requires special modifications to the application so that only particular aspects of the application's functionality occur when replaying the transactions, as other aspects (for example, billing the customer for the order) were already performed by the pre-upgrade version of the application. Such attempts still also suffer from the merge and ordering difficulties.
It is therefore desirable to provide upgrading techniques that require little downtime by allowing multiple versions of the same database application to run concurrently during the upgrade process. It is also desirable to provide upgrading techniques that do not require the unnecessary duplication, modification, or reconfiguration of application components, such as clients, objects, and data. Finally, it is also desirable to provide more reliable mechanisms for maintaining data integrity between two concurrently running versions of a database application.